package com.tangding.controller;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.google.common.base.Strings;
import com.tangding.annotations.AuthRequire;
import com.tangding.common.logx.LogHelp;
import com.tangding.common.tools.ErrorConstants;
import com.tangding.common.utils.DateUtils;
import com.tangding.common.utils.Utils;
import com.tangding.enums.Auth;
import com.tangding.pojo.request.BaseParams;
import com.tangding.pojo.request.file.UploadTxtParams;
import com.tangding.pojo.response.MessageDto;

/**
 * @description
 *
 * @author Ranger
 * @version 2017年8月31日_下午3:09:04
 *
 */
@Controller
@RequestMapping("/file")
public class FileController {
	
	@Value("${logPath:/usr/log/}")
	String logPath;
	int avatarBalanceSum = 100;
	
	@PostConstruct
	public void init() {
		if (!logPath.endsWith("/") && !logPath.endsWith("\\") && !logPath.endsWith(File.separator)) {
			logPath += File.separator;
		}
	}
	
	@ResponseBody
	@RequestMapping(value = "/log/upload", method = RequestMethod.POST)
	@AuthRequire(Auth.LOGIN)
	public MessageDto handleLogFileUpload(@RequestParam("log") MultipartFile file, UploadTxtParams params) {
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			if (file == null || file.isEmpty()) {
				return MessageDto.responseFail(ErrorConstants.ERR_EMPTY_UPLOAD_FILE);
			}
			
			String originalFilename = file.getOriginalFilename();
			if (Strings.isNullOrEmpty(originalFilename) || originalFilename.indexOf(".") == -1) {
				return MessageDto.responseFail(ErrorConstants.ILLEGAL_UPLOAD_FILE_FORMAT);
			}
			
			String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
			if (!suffix.endsWith("txt")) {
				return MessageDto.responseFail(ErrorConstants.ILLEGAL_UPLOAD_FILE_FORMAT);
			}
			
			Object uid = SecurityUtils.getSubject().getSession().getAttribute("uid");
			String picPath = logPath + Utils.hashRule(avatarBalanceSum, String.valueOf(uid)) + File.separator;
			File dir = new File(picPath);
			if (!dir.exists()) {
				dir.mkdirs();
			}
			
			String fileName = Utils.getMD5(DateUtils.getMillisNow() + "") + "_" + DateUtils.formatDate(DateUtils.DATE_FORMAT + "_HH-mm-ss");
			File checkFile = new File(picPath + fileName);
			while (checkFile.exists()) {
				fileName = Utils.getMD5(DateUtils.getMillisNow() + "") + "_" + DateUtils.formatDate(DateUtils.DATE_FORMAT + "_HH-mm-ss");
				checkFile = new File(picPath + fileName);
			}
			
			FileWriter(file, picPath, fileName, suffix);//异步写文件
			
			/*UpdateUserRequest request = new UpdateUserRequest();
			request.setUid(params.getUid());
			request.setHeadUrl(fileName + suffix);
			int response = userService.updateSummary(request);
			if (response == 0) {
				return MessageDto.responseFail(ErrorConstants.FAIL, "image upload fail!");
			}
			int balanceId = Utils.hashRule(avatarBalanceSum, params.getUid());
			result.put("avatar", path + balanceId + File.separator + fileName + suffix);*/
		} catch (Exception e) {
			LogHelp.doLogException(e);
			return MessageDto.responseFail(ErrorConstants.FAIL, "file upload fail!");
		}
		return MessageDto.responseSuccess(result);
	}

	// 多文件上传
	@ResponseBody
	@RequestMapping(value = "/batch/upload", method = RequestMethod.POST)
	@AuthRequire(Auth.LOGIN)
	public MessageDto handleFileUpload(@RequestParam("file") MultipartFile[] files, BaseParams params) {
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			MultipartFile file = null;
			String msg = "";
			Map<String, Object> data = new HashMap<String, Object>();
			for (int i = 0; i < files.length; ++i) {
				file = files[i];
				if (!file.isEmpty()) {
					Object uid = SecurityUtils.getSubject().getSession().getAttribute("uid");
					String picPath = logPath + Utils.hashRule(avatarBalanceSum, String.valueOf(uid)) + File.separator;
					File dir = new File(picPath);
					if (!dir.exists()) {
						dir.mkdirs();
					}
					
					String fileName = Utils.getMD5(file.getOriginalFilename() + DateUtils.getMillisNow());
					File checkFile = new File(picPath + fileName);
					while (checkFile.exists()) {
						fileName = Utils.getMD5(file.getOriginalFilename() + DateUtils.getMillisNow() + Utils.randomString(5));
						checkFile = new File(picPath + fileName);
					}
					
					data.put("" + i, fileName);
					FileWriter(file, picPath, fileName, file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")));
				} else {
					msg += i + ", ";
				}
			}
			result.put("images", data);
			if (msg.length() > 0) {
				msg = "empty pic[" + msg.substring(0, msg.length() - 1) + "]";
				return MessageDto.responseFail(ErrorConstants.ERR_EMPTY_UPLOAD_PIC, msg);
			}
		} catch (Exception e) {
			LogHelp.doLogException(e);
			return MessageDto.responseFail(ErrorConstants.FAIL, "image upload fail!");
		}
		return MessageDto.responseSuccess(result);
	}
	
	@Async
	public void FileWriter(MultipartFile file, String picPath, String fileName, String suffix) {
		BufferedOutputStream stream = null;
		try {
			byte[] bytes = file.getBytes();
			stream = new BufferedOutputStream(new FileOutputStream(new File(picPath + fileName + suffix)));
			stream.write(bytes);
			stream.flush();
		} catch (Exception e) {
			LogHelp.doLogException(e);
		} finally {
			try {
				stream.close();
			} catch (IOException e) {
				LogHelp.doLogException(e);
			}
		}
	}
}